home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / nff / filter.c / text0000.txt < prev   
Encoding:
Text File  |  1992-12-02  |  5.0 KB  |  246 lines

  1. I am posting the source code since among the people
  2. who requested for the source code, two of them are
  3. not reach-able from my system. Fortunately it's not a
  4. big program. Sorry for the inconvenience.
  5. ***
  6. /*
  7.  * program: nfff.c
  8.  *
  9.  *    a filter for NFF (Neutral File Format)
  10.  *    nfff [infile]
  11.  *    input: infile.nff or stdin
  12.  *    output: stdout
  13.  *
  14.  * input items other than polygons are copied to output directly.
  15.  * for polygons that have 2 or more identical vertices, the redundant
  16.  * vertices are filtered out and the "p <vert_count>" lines of
  17.  * the polygons are adjusted properly.
  18.  *
  19.  * the vertices degeneration cases occur in data produced by some
  20.  * automatic nff generation program when the resolution/prec. of
  21.  * generation exceeds that of the floating point format.
  22.  *
  23.  * definition of NFF: see nff.def
  24.  * bugs:
  25.  *    (1) handles polygons only. break if there are other obj. types
  26.  *    (2) MAX_VERT may cause trouble
  27.  *
  28.  * Fri Dec  2 16:41:27 EST 1988
  29.  * pkh@vap
  30.  *
  31.  * bugs fixed:
  32.  *
  33.  */
  34. #include    <stdio.h>
  35. #include    <math.h>
  36. /* #include    "/usr/pkh/include/all.h" */
  37. /* #include    "/usr/pkh/include/def3d.h" */
  38.  
  39. /* from "def3d.h" */
  40. typedef struct pt3d_struct {
  41.     float x, y, z;
  42. } pt3d, *pt3d_t;
  43. #define    FPRINT3d(fp, pt, newline) do { \
  44.     if (newline) \
  45.         fprintf(fp, "%g %g %g\n", pt.x, pt.y, pt.z); \
  46.     else \
  47.         fprintf(fp, "%g %g %g", pt.x, pt.y, pt.z); \
  48. } while (0)
  49. #define FSCAN3d(fp, pt) do { \
  50.     fscanf(fp,"%f %f %f", &(pt.x), &(pt.y), &(pt.z)); \
  51. } while(0)
  52. #define ASSIGN3d(p0, p1) do {p0.x=p1.x; p0.y=p1.y; p0.z=p1.z;} while(0)
  53. #define EQ3d(p0, p1) ((p0.x==p1.x)&&(p0.y==p1.y)&& (p0.z==p1.z))
  54.  
  55. /* from "all.h" */
  56. int    debug;
  57. #define POW2(y)        (1<<y)
  58. #define    ERROR_MSG_LENGTH    (200)
  59. #define DEBUG(arg) \
  60. do { \
  61.     char msg[ERROR_MSG_LENGTH]; \
  62.     if (debug) { \
  63.         sprintf arg; \
  64.          fprintf(stderr, "%s", msg); \
  65.     } \
  66. } while (0)
  67. #define ERROR(arg) \
  68. do { \
  69.     char msg[ERROR_MSG_LENGTH]; \
  70.         sprintf arg; \
  71.          fprintf(stderr, "%s", msg); \
  72.         exit(0); \
  73. } while (0)
  74.  
  75. #define        MAX_VERT    POW2(12)    /* 4k verts per poly */
  76. pt3d *v;    /* array of dim MAX_VERT */
  77.  
  78. FILE    *nfffile;
  79. char    infile[25];
  80.  
  81. /*
  82.  * for statistics
  83.  */
  84. int    total_byte;    /* total byte allocated */
  85. int    poly_id;
  86.  
  87. /*
  88.  * copy to end of line
  89.  */
  90. copy_line(ifp, ofp)
  91. FILE *ifp, *ofp;
  92. {
  93.     char c;
  94.     do {
  95.         putc((c=getc(ifp)), ofp);
  96.     } while (c!='\n');
  97. }
  98.  
  99. int read_poly(fp)
  100. FILE *fp;
  101. {
  102.     int             tv;
  103.     int             i;
  104.  
  105.     fscanf(fp, "%d", &tv);
  106.  
  107.     for (i = 0; i < tv; i++) {
  108.         FSCAN3d(fp,(v[i]));
  109.     }
  110.     return (tv);
  111. }
  112.  
  113. /*
  114.  * filter out degenerated (redundant) vertices
  115.  * and return the true vert count.
  116.  * complain when polygon has less than 3 vert
  117.  */
  118. int vert_filter(in_vert)
  119. int in_vert;
  120. {
  121.     int             head, tail;
  122.     int             tv, skip;
  123.  
  124.     /*
  125.      * filter out degenerated vertices. head points to the verified vert,
  126.      * tail scans down the vert list for new vert.
  127.      */
  128.     head = 0;        /* points to v[0] */
  129.     tail = head + 1;    /* points to v[1] */
  130.     tv = 1;            /* count one vert already (v[0]) */
  131.     skip = 0;        /* "skip occured" flag */
  132.     do {
  133.         while (EQ3d((v[head]), (v[tail]))) {
  134.             tail++;
  135.             if (tail == in_vert)
  136.                 goto last_vert;
  137.             skip = 1;
  138.         }
  139.         if (skip) {
  140.             ASSIGN3d((v[head + 1]), (v[tail]));
  141.         }
  142.         head++;
  143.         tail++;
  144.     } while (tail < in_vert);
  145.  
  146.     /* head now points to the last valid vert. compare last and first */
  147. last_vert:if (EQ3d((v[0]), v[head]))
  148.         tv = head;
  149.     else
  150.         tv = head + 1;
  151.     if (tv < 3) {
  152.         ERROR((msg, "poly %d has less than 3 vert\n", poly_id));
  153.         write_polygon(stderr, tv);    /* write vert */
  154.     }
  155.     if (debug) {
  156.         write_polygon(stderr, tv);    /* write vert */
  157.     }
  158.     return (tv);
  159. }
  160.  
  161. /*
  162.  * write out the cleaned-up polygons in nff format
  163.  * also print out the poly id
  164.  */
  165. write_polygon(fp, ply_vert)
  166. FILE *fp;
  167. int ply_vert;
  168. {
  169.     int             j;
  170.  
  171.     fprintf(fp, "# p%d\np %d\n", poly_id, ply_vert);
  172.     for (j = 0; j < ply_vert; j++) {
  173.         FPRINT3d(fp, (v[j]), 0);
  174.         fprintf(fp, "\n");
  175.     }
  176. }
  177.  
  178. /*
  179.  * for polygons: read-filter-write
  180.  * for the rest: read-write
  181.  */
  182. read_write(ifp, ofp)
  183. FILE *ifp, *ofp;
  184. {
  185.     char            key[20];
  186.     int             in_vert, out_vert;
  187.  
  188.     /* read "key" */
  189.     while (fscanf(ifp, "%s", key) != EOF) {
  190.  
  191.         DEBUG((msg, "get key %s\n", key));
  192.         if (strcmp(key, "p") == 0) {
  193.             in_vert = read_poly(ifp);
  194.             out_vert = vert_filter(in_vert);
  195.             write_polygon(ofp, out_vert);
  196.             poly_id++;
  197.         } else {
  198.             fprintf(ofp, "%s ", key);
  199.             copy_line(ifp, ofp);
  200.         }
  201.     };
  202. }
  203.  
  204. init()
  205. {
  206.     int             new_byte;
  207.  
  208.     new_byte = sizeof(pt3d) * MAX_VERT;
  209.     total_byte += new_byte;
  210.     v = (pt3d_t) malloc(new_byte);
  211.     DEBUG((msg, "v alloc %3dB; total %5dB\n", new_byte, total_byte));
  212.     if (v == NULL)
  213.         ERROR((msg, "v array alloc err\n"));
  214.  
  215.     poly_id = 0;
  216. }
  217.  
  218. main(argc, argv)
  219. int    argc;
  220. char    *argv[];
  221. {
  222.     if (argc == 1) {
  223.         nfffile= stdin;
  224.     }
  225.     else if (argc == 2) {
  226.         /* ap
  227. } pend .nff suffix */
  228.         sprintf(infile, "%s.nff", argv[1]);
  229.         if ((nfffile= fopen(infile, "r")) == NULL) {
  230.             ERROR((msg, "input file %s not found\n", infile));
  231.             exit(1);
  232.         }
  233.     } else {
  234.         ERROR((msg, "Usage: %s [file].nff\n", argv[0]));
  235.         exit(1);
  236.     }
  237.  
  238.     debug = 0;
  239.  
  240.     init();
  241.  
  242.     fprintf(stdout, "#\n# polygons filtered by nfffilter program\n");
  243.     fprintf(stdout, "# date:\n#\n");
  244.     read_write(nfffile, stdout);
  245. }
  246.